package com.xbongbong.formula.qlexpress.operator.text;

import com.ql.util.express.Operator;
import com.ql.util.express.OperatorOfNumber;
import com.xbongbong.formula.enums.TextTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.MathUtil;
import com.xbongbong.paas.toolbox.util.PaasDateUtil;
import com.xbongbong.paas.toolbox.util.RegexUtil;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.WeekEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessRuleErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Objects;

/**
 * https://xbb.yuque.com/lfwuxq/vsf9sv/il4g4v#text
 * @author: wufeng
 * @date: 2018/7/5 15:22
 * @desrcption: 将文本转化为数字。
 */
public class OperatorText extends Operator {

    public OperatorText(String name){
        this.name = name;
    }

    public OperatorText(String aliasName, String aName, String errorInfo){
        this.aliasName = aliasName;
        this.name = aName;
        this.errorInfo = errorInfo;
    }

    /**
     * @param list
     * list[0] 将数字转化成文本。
     * list[1] 将数字转换成特定格式的文本
     * @return
     * @throws Exception
     */
    @Override
    public Object executeInner(Object[] list) throws Exception {

        if (Objects.isNull(list)) {
            throw new XbbException(BusinessRuleErrorCodeEnum.API_ERROR_261007);
        }
        String firstString = list[0].toString();
        String textFormat = TextTypeEnum.ROW_DATA_FORMAT.getType();
        if (list.length > 1) {
            textFormat = list[1].toString();
        }
        if (RegexUtil.decimalFormat(textFormat)) {
            // #.##
            return decimalFormat(textFormat, firstString);
        } else if (RegexUtil.numericPlaceholder(textFormat)) {
            int num = textFormat.length() - textFormat.indexOf(".") -1;
            int valueNum = firstString.length() - firstString.indexOf(".") -1;
            if (num > valueNum) {
                DecimalFormat decimalFormat = new DecimalFormat(textFormat);
                BigDecimal bigDecimal = new BigDecimal(Double.valueOf(firstString));
                return decimalFormat.format(bigDecimal);
            }
            return firstString;
        } else if (RegexUtil.decimalPercentSignFormat(textFormat)) {
            // 百分比 #.##%
            textFormat = textFormat.replaceAll("%", "");
            Number number = OperatorOfNumber.multiply(Double.valueOf(firstString), 100, true);
            Object result = decimalFormat(textFormat, String.valueOf(number.doubleValue()));
            return  result+ "%";
        } else if (RegexUtil.rowDataFormat(textFormat)) {
            return textFormat.replaceAll("\\[Num0\\]", firstString);
        } else if (Objects.equals(TextTypeEnum.LOW_CHINESE_FORMAT.getType(), textFormat)) {
           return lowChineseFormat(list[0]);
        } else if (Objects.equals(TextTypeEnum.UPPER_CHINESE_FORMAT.getType(), textFormat)) {
            return upperChineseFormat(list[0]);
        } else if (Objects.equals(TextTypeEnum.YEAR_FORMAT.getType(), textFormat)) {
            Long time = PaasDateUtil.getInt(list[0]);
            if (Objects.isNull(time)) {
                return null;
            }
            return DateTimeUtil.getYear(time);
        } else if (Objects.equals(TextTypeEnum.MONTH_FORMAT.getType(), textFormat)) {
            Long time = PaasDateUtil.getInt(list[0]);
            if (Objects.isNull(time)) {
                return null;
            }
            return DateTimeUtil.getMonth(time);
        } else if (Objects.equals(TextTypeEnum.DAY_FORMAT.getType(), textFormat)) {
            Long time = PaasDateUtil.getInt(list[0]);
            if (Objects.isNull(time)) {
                return null;
            }
            return DateTimeUtil.getDay(time);
        } else if (Objects.equals(TextTypeEnum.HOUR_FORMAT.getType(), textFormat)) {
            Long time = PaasDateUtil.getInt(list[0]);
            Integer hour = DateTimeUtil.getHourSomeday(time);
            if (Objects.isNull(hour)) {
                return null;
            }
            return String.valueOf(hour);
        } else if (Objects.equals(TextTypeEnum.MINUTES_FORMAT.getType(), textFormat)) {
            Long time = PaasDateUtil.getInt(list[0]);
            Integer minutes = DateTimeUtil.getMinuteSomeday(time);
            if (Objects.isNull(minutes)) {
                return null;
            }
            return String.valueOf(minutes);
        } else if (Objects.equals(TextTypeEnum.SECOND_FORMAT.getType(), textFormat)) {
            Long time = PaasDateUtil.getInt(list[0]);
            Integer second = DateTimeUtil.getSecondSomeday(time);
            if (Objects.isNull(second)) {
                return null;
            }
            return String.valueOf(second);
        } else if (Objects.equals(TextTypeEnum.WEEK_E.getType(), textFormat)) {
            Long time = PaasDateUtil.getInt(list[0]);
            Integer second = DateTimeUtil.getWeekInSomeday(time);
            if (Objects.isNull(second)) {
                return null;
            }
            return second;
        } else if (Objects.equals(TextTypeEnum.WEEK_EE.getType(), textFormat)) {
            Long time = PaasDateUtil.getInt(list[0]);
            Integer week = DateTimeUtil.getWeekInSomeday(time);
            if (Objects.isNull(week)) {
                return null;
            }
            WeekEnum weekEnum = WeekEnum.getByCode(week+1);
            if (Objects.isNull(weekEnum)) {
                return null;
            }
            return weekEnum.getName().replace("星期", "");
        } else if (Objects.equals(TextTypeEnum.WEEK_EEE.getType(), textFormat)) {
            Long time = PaasDateUtil.getInt(list[0]);
            Integer week = DateTimeUtil.getWeekInSomeday(time);
            if (Objects.isNull(week)) {
                return null;
            }
            WeekEnum weekEnum = WeekEnum.getByCode(week+1);
            if (Objects.isNull(weekEnum)) {
                return null;
            }
            return weekEnum.getName();
        } else {
            Long time = PaasDateUtil.getInt(list[0]);
            return DateTimeUtil.getStringEpochSecond(time, textFormat);
        }
    }

    private static Object decimalFormat(String textFormat, String firstString) {
        int start = textFormat.indexOf(".");
        int scale = textFormat.length() - start -1;
        DecimalFormat decimalFormat = new DecimalFormat(textFormat);
        BigDecimal bigDecimal = MathUtil.ceil(Double.valueOf(firstString), scale);
        return decimalFormat.format(bigDecimal);
    }

    /**
     * 简体字
     * @param value
     * @return
     */
    public static String lowChineseFormat(Object value) throws Exception {
        final String[] num = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        final String[] unit = {"", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千"};
        String dst = "";
        int count = 0;
        if (value instanceof Double || value instanceof Float) {
            Double src = Double.valueOf(String.valueOf(value));
            String[] valueStr = String.valueOf(src).split("\\.");
            Long numInteger = Long.valueOf(valueStr[0]);
            dst = getString(numInteger, num, unit);
            dst = dst.replaceAll("零[千百十]", "零").replaceAll("零+万", "万")
                    .replaceAll("零+亿", "亿").replaceAll("亿万", "亿零")
                    .replaceAll("零+", "零").replaceAll("零$", "");
            Integer decimalPlaces = Integer.valueOf(valueStr[1]);

            count = 0;
            String decimalPlacesStr = "";
            while(decimalPlaces > 0) {
                Number number = (Number) OperatorOfNumber.modulo(decimalPlaces, 10);
                decimalPlacesStr = (num[number.intValue()]) + decimalPlacesStr;
                decimalPlaces = decimalPlaces / 10;
                count++;
            }
            decimalPlacesStr = decimalPlacesStr.replaceAll("零+", "零").replaceAll("零$", "");
            return dst +"点"+ decimalPlacesStr;
        } else {
            Long numInteger = Long.valueOf(String.valueOf(value));
            dst = getString(numInteger, num, unit);
            return dst.replaceAll("零[千百十]", "零").replaceAll("零+万", "万")
                    .replaceAll("零+亿", "亿").replaceAll("亿万", "亿零")
                    .replaceAll("零+", "零").replaceAll("零$", "");
        }

    }

    /**
     * 繁体字
     * @param value
     * @return
     */
    public static String upperChineseFormat(Object value) throws Exception {
        final String[] num = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
        final String[] unit = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"};
        String dst = "";
        int count = 0;
        if (value instanceof Double || value instanceof Float) {
            Double src = Double.valueOf(String.valueOf(value));
            String symbol = "";
            if (src < BasicConstant.ZERO_DOUBLE){
                symbol = "负";
            }
            src = Math.abs(src);
            // 解开e或者E
            DecimalFormat decimalFormat = new DecimalFormat("#.######");

            String[] valueStr = decimalFormat.format(src).split("\\.");
            Long numInteger = Long.valueOf(valueStr[0]);
            dst = getString(numInteger, num, unit);
            dst = dst.replaceAll("零[仟佰拾]", "零").replaceAll("零+万", "万")
                    .replaceAll("零+亿", "亿").replaceAll("亿万", "亿零")
                    .replaceAll("零+", "零").replaceAll("零$", "");
            Integer decimalPlaces = Integer.valueOf(valueStr[1]);

            count = 0;
            String decimalPlacesStr = "";
            while(decimalPlaces > 0) {
                Number number = (Number) OperatorOfNumber.modulo(decimalPlaces, 10);
                decimalPlacesStr = (num[number.intValue()]) + decimalPlacesStr;
                decimalPlaces = decimalPlaces / 10;
                count++;
            }
            decimalPlacesStr = decimalPlacesStr.replaceAll("零+", "零").replaceAll("零$", "");
            return symbol + dst +"点"+ decimalPlacesStr;
        } else {
            Long numInteger = Long.valueOf(String.valueOf(value));
            if (Objects.isNull(value)){
                return "零元整";
            }
            String symbol = "";
            if (numInteger < BasicConstant.ZERO_LONG) {
                symbol = "负";
            }
            numInteger = Math.abs(numInteger);
            dst = getString(numInteger, num, unit).replaceAll("零[仟佰拾]", "零").replaceAll("零+万", "万")
                    .replaceAll("零+亿", "亿").replaceAll("亿万", "亿零")
                    .replaceAll("零+", "零").replaceAll("零$", "");
            return symbol + dst;
        }

    }

    private static String getString(Long numInteger, String[] num, String[] unit) throws Exception {
        Integer count = 0;
        String dst = "";
        while(numInteger > 0) {
            Number number = (Number) OperatorOfNumber.modulo(numInteger, 10);
            dst = (num[number.intValue()] + unit[count]) + dst;
            numInteger = numInteger / 10;
            count++;
        }
        return dst;
    }
}

